/**
 * @file test_pcie_filelist.cpp
 * @brief 专门测试PCIe DWC_pcie_dm.lst文件列表的解析
 * 这是一个包含大量复杂Verilog文件的真实工业级PCIe IP测试
 */

#include "../moparse.h"
#include <iostream>
#include <fstream>
#include <chrono>
#include <functional>

class PCIeFilelistTestRunner {
public:
    PCIeFilelistTestRunner() : tests_passed_(0), tests_failed_(0) {}
    
    void run_test(const std::string& test_name, std::function<bool()> test_func) {
        std::cout << "运行PCIe测试: " << test_name << " ... ";
        auto start = std::chrono::high_resolution_clock::now();
        
        try {
            if (test_func()) {
                auto end = std::chrono::high_resolution_clock::now();
                auto duration = std::chrono::duration_cast<std::chrono::milliseconds>(end - start);
                std::cout << "通过 (" << duration.count() << "ms)" << std::endl;
                tests_passed_++;
            } else {
                std::cout << "失败" << std::endl;
                tests_failed_++;
            }
        } catch (const std::exception& e) {
            std::cout << "异常: " << e.what() << std::endl;
            tests_failed_++;
        }
    }
    
    void print_summary() {
        std::cout << "\nPCIe文件列表测试总结:" << std::endl;
        std::cout << "通过: " << tests_passed_ << std::endl;
        std::cout << "失败: " << tests_failed_ << std::endl;
        std::cout << "总计: " << (tests_passed_ + tests_failed_) << std::endl;
        
        if (tests_failed_ == 0) {
            std::cout << "\n🎉 所有PCIe测试都通过了！" << std::endl;
        } else {
            std::cout << "\n⚠️  有 " << tests_failed_ << " 个测试失败。" << std::endl;
        }
    }
    
    int get_failed_count() const { return tests_failed_; }

private:
    int tests_passed_;
    int tests_failed_;
};

// 检查文件是否存在的辅助函数
bool file_exists(const std::string& filename) {
    std::ifstream file(filename);
    return file.good();
}

// 获取文件大小的辅助函数
long get_file_size(const std::string& filename) {
    std::ifstream file(filename, std::ifstream::ate | std::ifstream::binary);
    return file.tellg();
}

// 分析文件列表内容
bool analyze_filelist() {
    std::string filelist_path = "../../a9soc/design/pcie/src/DWC_pcie_dm.lst";
    
    if (!file_exists(filelist_path)) {
        std::cout << "文件列表不存在: " << filelist_path;
        return false;
    }
    
    std::ifstream filelist(filelist_path);
    if (!filelist.is_open()) {
        return false;
    }
    
    int total_files = 0;
    int existing_files = 0;
    int verilog_files = 0;
    int header_files = 0;
    long total_size = 0;
    
    std::string line;
    while (std::getline(filelist, line)) {
        // 跳过注释行和空行
        if (line.empty() || line[0] == '/' || line.find("//") == 0 || line.find("component:") != std::string::npos) {
            continue;
        }
        
        total_files++;
        
        if (file_exists(line)) {
            existing_files++;
            long size = get_file_size(line);
            total_size += size;
            
            if (line.find(".v") != std::string::npos) {
                verilog_files++;
            } else if (line.find(".vh") != std::string::npos) {
                header_files++;
            }
        }
    }
    
    std::cout << "文件统计: 总计" << total_files << "个，存在" << existing_files 
              << "个，Verilog文件" << verilog_files << "个，头文件" << header_files 
              << "个，总大小" << (total_size/1024) << "KB ";
    
    return existing_files > 0;
}

// 尝试解析完整的PCIe文件列表
bool test_full_pcie_filelist() {
    std::string filelist_path = "../../a9soc/design/pcie/src/DWC_pcie_dm.lst";
    
    if (!file_exists(filelist_path)) {
        std::cout << "文件列表不存在 ";
        return false;
    }
    
    VerilogParser parser;
    
    // 尝试直接解析文件列表
    if (!parser.parseVerilogFileList(filelist_path)) {
        std::cout << "文件列表解析失败 ";
        return false;
    }
    
    const auto& db = parser.getDatabase();
    std::cout << "解析出 " << db.modules_size() << " 个模块 ";
    
    // 尝试保存到modb文件
    if (!parser.saveToModb("pcie_dm_full.modb")) {
        std::cout << "保存modb失败 ";
        return false;
    }
    
    return db.modules_size() > 0;
}

// 逐个解析PCIe文件（更安全的方法）
bool test_individual_pcie_files() {
    std::string filelist_path = "../../a9soc/design/pcie/src/DWC_pcie_dm.lst";
    
    if (!file_exists(filelist_path)) {
        std::cout << "文件列表不存在 ";
        return false;
    }
    
    std::ifstream filelist(filelist_path);
    VerilogParser parser;
    
    int processed_files = 0;
    int successful_files = 0;
    std::string line;
    
    while (std::getline(filelist, line) && processed_files < 10) {  // 限制前10个文件避免超时
        // 跳过注释行和空行
        if (line.empty() || line[0] == '/' || line.find("//") == 0 || line.find("component:") != std::string::npos) {
            continue;
        }
        
        processed_files++;
        
        if (file_exists(line) && line.find(".v") != std::string::npos) {
            if (parser.parseVerilogFile(line)) {
                successful_files++;
                std::cout << "✓";
            } else {
                std::cout << "✗";
            }
        } else {
            std::cout << "?";  // 文件不存在或非Verilog文件
        }
    }
    
    const auto& db = parser.getDatabase();
    std::cout << " 成功 " << successful_files << "/" << processed_files 
              << " 文件，共 " << db.modules_size() << " 个模块 ";
    
    return successful_files > 0;
}

// 测试头文件和常量文件的处理
bool test_pcie_headers_and_constants() {
    std::vector<std::string> test_files = {
        "../../a9soc/design/pcie/src/DWC_pcie_dm_cc_constants.v",
        "../../a9soc/design/pcie/src/include/pcie_defs.vh",
        "../../a9soc/design/pcie/src/include/cxpl_defs.vh",
        "../../a9soc/design/pcie/src/Axi/DWC_pcie_axi_gm_constants.v",
        "../../a9soc/design/pcie/src/Edma/DWC_pcie_edma_constants.v"
    };
    
    VerilogParser parser;
    int successful_files = 0;
    
    for (const auto& file : test_files) {
        if (file_exists(file)) {
            if (parser.parseVerilogFile(file)) {
                successful_files++;
                std::cout << "✓";
            } else {
                std::cout << "✗";
            }
        } else {
            std::cout << "?";
        }
    }
    
    const auto& db = parser.getDatabase();
    std::cout << " 成功 " << successful_files << "/" << test_files.size() 
              << " 文件，解析出 " << db.modules_size() << " 个模块，" 
              << db.macros_size() << " 个宏定义 ";
    
    return successful_files > 0;
}

// 测试PCIe核心模块
bool test_pcie_core_modules() {
    std::vector<std::string> core_modules = {
        "../../a9soc/design/pcie/src/DWC_pcie_dm.v",
        "../../a9soc/design/pcie/src/Layer1/rmlh.v", 
        "../../a9soc/design/pcie/src/Layer2/rdlh.v",
        "../../a9soc/design/pcie/src/Layer3/rtlh.v",
        "../../a9soc/design/pcie/src/Adm/xadm.v"
    };
    
    VerilogParser parser;
    int successful_files = 0;
    
    for (const auto& file : core_modules) {
        if (file_exists(file)) {
            if (parser.parseVerilogFile(file)) {
                successful_files++;
                std::cout << "✓";
            } else {
                std::cout << "✗";
            }
        } else {
            std::cout << "?";
        }
    }
    
    const auto& db = parser.getDatabase();
    std::cout << " 成功 " << successful_files << "/" << core_modules.size() 
              << " 核心模块，解析出 " << db.modules_size() << " 个模块 ";
    
    return successful_files > 0;
}

// 性能测试：批量处理能力
bool test_pcie_batch_performance() {
    std::string filelist_path = "../../a9soc/design/pcie/src/DWC_pcie_dm.lst";
    
    if (!file_exists(filelist_path)) {
        std::cout << "文件列表不存在 ";
        return false;
    }
    
    auto start = std::chrono::high_resolution_clock::now();
    
    VerilogParser parser;
    bool result = false;
    
    try {
        result = parser.parseVerilogFileList(filelist_path);
    } catch (...) {
        std::cout << "批量解析时发生异常 ";
        return false;
    }
    
    auto end = std::chrono::high_resolution_clock::now();
    auto duration = std::chrono::duration_cast<std::chrono::milliseconds>(end - start);
    
    if (result) {
        const auto& db = parser.getDatabase();
        std::cout << "批量解析完成，" << db.modules_size() << " 个模块，" 
                  << db.macros_size() << " 个宏定义，耗时 " << duration.count() << "ms ";
    } else {
        std::cout << "批量解析失败，耗时 " << duration.count() << "ms ";
    }
    
    return result;
}

// 生成和验证modb文件
bool test_modb_generation_verification() {
    VerilogParser parser1, parser2;
    
    // 尝试解析几个关键文件
    std::vector<std::string> key_files = {
        "../../a9soc/design/pcie/src/DWC_pcie_dm_cc_constants.v",
        "../../a9soc/design/pcie/src/common/delay_n.v",
        "../../a9soc/design/pcie/src/common/DWC_pcie_bcm01.v"
    };
    
    int parsed_files = 0;
    for (const auto& file : key_files) {
        if (file_exists(file)) {
            if (parser1.parseVerilogFile(file)) {
                parsed_files++;
            }
        }
    }
    
    if (parsed_files == 0) {
        std::cout << "没有成功解析任何文件 ";
        return false;
    }
    
    // 保存到modb
    if (!parser1.saveToModb("pcie_test.modb")) {
        std::cout << "保存modb失败 ";
        return false;
    }
    
    // 验证加载
    if (!parser2.loadFromModb("pcie_test.modb")) {
        std::cout << "加载modb失败 ";
        return false;
    }
    
    const auto& db1 = parser1.getDatabase();
    const auto& db2 = parser2.getDatabase();
    
    bool modules_match = (db1.modules_size() == db2.modules_size());
    bool macros_match = (db1.macros_size() == db2.macros_size());
    
    std::cout << "解析" << parsed_files << "文件，模块一致性:" << (modules_match ? "✓" : "✗")
              << "，宏定义一致性:" << (macros_match ? "✓" : "✗") << " ";
    
    // 清理
    std::remove("pcie_test.modb");
    
    return modules_match && macros_match;
}

int main() {
    std::cout << "开始PCIe DWC_pcie_dm.lst文件列表测试...\n" << std::endl;
    
    PCIeFilelistTestRunner runner;
    
    // 运行PCIe文件列表测试
    runner.run_test("文件列表分析", analyze_filelist);
    runner.run_test("头文件和常量文件", test_pcie_headers_and_constants);
    runner.run_test("PCIe核心模块", test_pcie_core_modules);
    runner.run_test("单个文件解析", test_individual_pcie_files);
    runner.run_test("modb生成验证", test_modb_generation_verification);
    runner.run_test("批量处理性能", test_pcie_batch_performance);
    runner.run_test("完整文件列表解析", test_full_pcie_filelist);
    
    // 输出测试结果
    runner.print_summary();
    
    return runner.get_failed_count() > 0 ? 1 : 0;
}